package com.huawei.lynnbit.tool.cocos.processor.leaf;

import com.huawei.lynnbit.tool.cocos.config.game.GameConfig;
import com.huawei.lynnbit.tool.cocos.config.game.task.CopyFileTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.CopySnippetTask;
import com.huawei.lynnbit.tool.cocos.config.game.task.Task;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class CopyProcessor extends LeafProcessor {
    public CopyProcessor(Task task, GameConfig gameConfig) {
        this.task = task;
        this.gameConfig = gameConfig;
    }

    @Override
    public void doProcess() throws IOException {
        processCopyFile();
        processCopySnippet();
    }

    private void processCopySnippet() throws IOException {
        if (!Task.TYPE_COPY_SNIPPET.equals(task.getType())) {
            return;
        }

        CopySnippetTask taskInfo = (CopySnippetTask) task;
        taskInfo.presetDestPath(gameConfig);
        if (isReadyCopyed(taskInfo)) {
            return;
        }

        if (StringUtils.isNotBlank(taskInfo.getDestLine())) {
            List<String> lines = FileUtils.readLines(new File(taskInfo.getDestPath()), StandardCharsets.UTF_8);
            lines.add(Integer.parseInt(taskInfo.getDestLine()) - 1, taskInfo.getSnippet());
            FileUtils.writeLines(new File(taskInfo.getDestPath()), StandardCharsets.UTF_8.name(), lines);
        } else if (StringUtils.isNotBlank(taskInfo.getDestPattern())) {
            String context = FileUtils.readFileToString(new File(taskInfo.getDestPath()), StandardCharsets.UTF_8);
            Pattern pattern = Pattern.compile(taskInfo.getDestPattern());
            Matcher matcher = pattern.matcher(context);
            if (matcher.find()) {
                String newContext = context.substring(0, matcher.end(0)) + taskInfo.getSnippet() + context.substring(matcher.end(0));
                FileUtils.write(new File(taskInfo.getDestPath()), newContext, StandardCharsets.UTF_8);
            } else {
                log.error("not match pattern: {}", taskInfo.getDestPattern());
                throw new IllegalStateException("not match pattern");
            }
        } else if (StringUtils.isNotBlank(taskInfo.getDestString())) {
            String context = FileUtils.readFileToString(new File(taskInfo.getDestPath()), StandardCharsets.UTF_8);
            int index = context.indexOf(taskInfo.getDestString());
            if (index == -1) {
                log.error("not match string: {}", taskInfo.getDestString());
                throw new IllegalStateException("not match string");
            }



            String newContext = context.substring(0, index) + taskInfo.getSnippet() + context.substring(index);
            FileUtils.write(new File(taskInfo.getDestPath()), newContext, StandardCharsets.UTF_8);
        }
    }

    private boolean isReadyCopyed(CopySnippetTask taskInfo) throws IOException {
        String context = FileUtils.readFileToString(new File(taskInfo.getDestPath()), StandardCharsets.UTF_8).replaceAll("(\n|\r\n)", "");
        return context.contains(taskInfo.getSnippet().replaceAll("(\n|\r\n)", ""));
    }

    private void processCopyFile() throws IOException {
        if (!Task.TYPE_COPY_FILE.equals(task.getType())) {
            return;
        }

        CopyFileTask taskInfo = (CopyFileTask) task;
        taskInfo.presetDestPath(gameConfig);
        File file = new File(taskInfo.getSrcPath());
        if (file.isFile()) {
            FileUtils.copyFile(new File(taskInfo.getSrcPath()), new File(taskInfo.getDestPath()));
        }

        if (file.isDirectory()) {
            FileUtils.copyDirectory(new File(taskInfo.getSrcPath()), new File(taskInfo.getDestPath()));
        }
    }
}
